﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Data;
using AcctrueWMS.Foundation.DAL;
using AcctrueWMS.Foundation.Util;
using System.Web;
namespace AcctrueWMS.Foundation.Data
{
    [Serializable]
    public class DataModel
    {
        /// <summary>
        /// 上下文
        /// </summary>
        IDataModelContext context;
        /// <summary>
        /// DataRow集合
        /// </summary>
        DataModelCollection datamodelCollection;
        /// <summary>
        /// DataRelation集合
        /// </summary>
        DataModelRelationCollection datamodelRelationCollection;
        /// <summary>
        /// DataColumn集合
        /// </summary>
        DataModelColumnCollection datamodelColumnCollection;
        /// <summary>
        /// Child集合
        /// </summary>
        DataModelCollection datamodelChildCollection;
        /// <summary>
        /// Brother集合
        /// </summary>
        DataModelCollection datamodelBrotherCollection;
        /// <summary>
        /// 列值集合
        /// </summary>
        Dictionary<string, DataModelCell> itemArray;
        /// <summary>
        /// DataModel列值的集合
        /// </summary>
        public Dictionary<string, DataModelCell> ItemArray
        {
            get
            {
                if (itemArray == null)
                    itemArray = new Dictionary<string, DataModelCell>();
                return this.itemArray;
            }
            set
            {
                this.itemArray = value;
            }
        }


        #region DataModel和DataTable的互操作
        /// <summary>
        /// 将DataTable对象转换为DataModel对象
        /// </summary>
        /// <param name="dt"></param>
        /// <param name="model"></param>
        public void FromDataTable(DataTable dt)
        {
            this.Rows.Clear();
            ///如果源DataTable为空,则不执行转换


            int currPage = int.Parse(DataHelper.CheckForNull(HttpContext.Current.Request.QueryString["currpage"], "0"));
            //url里的pagesize优先于模型中定义
            int pageSize = int.Parse(HttpContext.Current.Request.QueryString["pagesize"] != null ? HttpContext.Current.Request.QueryString["pagesize"] : "15");
            if (dt == null) return;
            var i = 1 + currPage * pageSize;
            foreach (DataRow row in dt.Rows)
            {
                DataModel modelRow = this.NewRow();
                ///2011-5-13 操敏删除,只从DataTable获取数据,结构从相应的xml文件获取
                //foreach (DataModelColumn column in model.Columns)
                //{
                //    modelRow.Columns.Add(column);
                //}

                modelRow.Rows.Add(modelRow);
                foreach (DataModelColumn column in this.Columns)
                {
                    //添加ROWNUM列值  create  by tianp   直接取行数作为行序号
                    if (column.Name == "ROWNUM")
                         modelRow[column.Name].Value = i;                   
                    else
                        modelRow[column.Name].Value = Context.GetCellValue(modelRow[column.Name], row);

                    modelRow[column.Name].Model = modelRow;
                    modelRow[column.Name].Column = column;//model的列名和datatable的列明相同
                    modelRow[column.Name].ColumnIndex = dt.Columns.IndexOf(column.Name);
                }

                i++;
                if (dt.PrimaryKey.Length > 0)
                {
                    this.KeyColumnName = dt.PrimaryKey[0].ColumnName;
                }
                this.Rows.Add(modelRow);
            }
        }
        /// <summary>
        /// 将DataModel换为DataTable
        /// </summary>
        /// <returns></returns>
        public DataTable ToDataTable()
        {
            string tableName = string.IsNullOrEmpty(this.physicalName) ? this.Name : this.physicalName;
            DataTable dt = new DataTable(tableName);
            Dictionary<string, Type> dirType = Web.TypeConverter.Converter.DirType;
            foreach (DataModelColumn column in this.Columns)
            {
                ///如果该列为虚拟列,则该数据不填充到用于保存的DataTable中
                if (column.physicalType == "virtual") continue;
                DataColumn dc = new DataColumn(column.Name);
                dc.DataType = column.ColumnType;
                FillModelCellFromTableCell(column, dc);

                dc.AllowDBNull = column.Nullable;
                //dc.MaxLength = column.MaxLength;
                dt.Columns.Add(dc);
            }
            ///设置主键
            if (!string.IsNullOrEmpty(KeyColumnName))
            {
                dt.PrimaryKey = new DataColumn[] { dt.Columns[this.KeyColumnName] };
            }
            if (dt.Columns.Count == 0)
                throw new Exception("DataTable中没有行");
            foreach (DataModel modelRow in this.Rows)
            {
                DataRow row = dt.NewRow();
                foreach (DataModelColumn column in this.Columns)
                {
                    ///如果该列为虚拟列,则该数据不填充到用于保存的DataTable中
                    if (column.physicalType == "virtual") 
                        continue;
                    if (modelRow[column.Name].Value == null || modelRow[column.Name].Value == System.DBNull.Value
                        || string.IsNullOrEmpty(modelRow[column.Name].Value.ToString().Trim()))
                    {
                        if (column.Nullable == true)
                            row[column.Name] = (object)DBNull.Value;
                        else
                        {
                            GetDefaultValueByType(column, row);
                        }
                    }
                    else
                        row[column.Name] = modelRow[column.Name].Value.ToString();
                }
                dt.Rows.Add(row);
            }
            return dt;
        }

        public void GetDefaultValueByType(DataModelColumn column, DataRow row)
        {
            switch (column.ColumnType.Name)
            {
                case "Int":
                    row[column.Name] = 0;
                    break;
                case "Int32":
                    row[column.Name] = 0;
                    break;
                case "Decimal":
                    row[column.Name] = 0;
                    break;
                case "DateTime":
                    row[column.Name] = System.DateTime.Parse("1900-01-01");
                    break;
                case "Float":
                    row[column.Name] = 0;
                    break;
                default:
                    row[column.Name] = (object)string.Empty;
                    break;
            }
        }

        private static void FillModelCellFromTableCell(DataModelColumn column, DataColumn dc)
        {
            switch (column.ColumnType.ToString())
            {
                case "System.Decimal":
                case "System.Int32":
                case "System.Float":

                    if (column.Default.Trim().Length == 0)
                    {
                        dc.DefaultValue = 0;
                    }
                    else
                        dc.DefaultValue = column.Default;
                    break;
                case "System.DateTime":
                    if (column.Default.Trim().Length == 0)
                    {
                        dc.DefaultValue = System.DBNull.Value;
                    }
                    else
                    {
                        dc.DefaultValue = Convert.ToDateTime(column.Default);
                    }
                    break;
                default:
                    break;
            }

        }
        #endregion

        public DataModel(IDataModelContext context, string modelName)
        {
            this.context = context;
            this.Name = modelName;
            context.FillModel(this);

            //itemArray = new Dictionary<string, DataModelCell>();
        }
        /// <summary>
        /// 上下文
        /// </summary>
        public IDataModelContext Context
        {
            get
            {
                return context;
            }
        }
        /// <summary>
        /// 主键列名 
        /// </summary>
        public string KeyColumnName
        {
            get;
            set;
        }
        /// <summary>
        /// wbs 生成配置
        /// </summary>
        public string WbsCodeGenType
        {
            get;
            set;
        }
        /// <summary>
        /// wbs列
        /// </summary>
        public string WbsCodeColumn
        {
            get;
            set;
        }
        /// <summary>
        /// Model名称
        /// </summary>
        public string Name
        {
            get;
            set;
        }
        /// <summary>
        /// 显示列
        /// </summary>
        public string DisplayName
        {
            get;
            set;
        }
        /// <summary>
        /// 物理表名
        /// </summary>
        public string  physicalName
        {
            get;
            set;
        }
        /// 是否分页
        /// </summary>
        public string ifPaging
        {
            get;
            set;
        }

        /// 是否在底层替换过滤条件（一般用与sys命令中的取数、报表中）
        /// </summary>
        public string ifChangeCon
        {
            get;
            set;
        }
        /// <summary>
        /// 数据类型
        /// </summary>
        public DataModelDataTypeEnum DataType
        {
            get;
            set;
        }
        /// <summary>
        /// 父Model
        /// </summary>
        public DataModel Parent
        {
            get;
            set;
        }
        /// <summary>
        /// 子Model
        /// </summary>
        public DataModelCollection Childs
        {
            get
            {
                if (datamodelChildCollection == null)
                    datamodelChildCollection = new DataModelCollection(this);
                return datamodelChildCollection;
            }
            set
            {
                this.datamodelChildCollection = value;
            }
        }
        /// <summary>
        /// 兄弟Model
        /// </summary>
        public DataModelCollection Brothers
        {
            get
            {
                if (datamodelBrotherCollection == null)
                    datamodelBrotherCollection = new DataModelCollection(this);
                return datamodelBrotherCollection;
            }
            set
            {
                datamodelBrotherCollection = value;
            }
        }
        /// <summary>
        /// 关系
        /// </summary>
        public DataModelRelationCollection Relations
        {
            get
            {
                if (datamodelRelationCollection == null)
                {
                    datamodelRelationCollection = new DataModelRelationCollection(this);
                }
                return datamodelRelationCollection;
            }

        }
        /// <summary>
        /// 生成命令,如果该属性不为空,则加载数据时,使用该属性填充数据
        /// </summary>
        public string GeneratingCommand
        {
            get;
            set;
        }
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public DataModel Select(string condition)
        {
            return context.Select(this, condition);
        }
        /// <summary>
        /// 分页查询并排序
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="orderBy"></param>
        /// <param name="startIndex"></param>
        /// <param name="endIndex"></param>
        /// <returns>返回DataModel集合</returns>
        public DataModel Select(string condition, string orderBy, int startIndex, int endIndex)
        {
            return Context.Select(this, condition, orderBy, startIndex, endIndex);
        }
        /// <summary>
        /// 分页查询
        /// </summary>
        /// <param name="condition"></param>
        /// <param name="start"></param>
        /// <param name="end"></param>
        /// <returns></returns>
        public DataModel Range(string condition, int start, int end)
        {
            return context.Range(this, condition, start, end);
        }
        /// <summary>
        /// 排序
        /// </summary>
        /// <param name="orderBy"></param>
        /// <returns></returns>
        public DataModel Order(string orderBy)
        {
            return context.Order(this, orderBy);
        }
        /// <summary>
        /// 属性访问器,根据列序号访问列
        /// </summary>
        /// <param name="index"></param>
        /// <returns></returns>
        public DataModelCell this[int index]
        {
            get
            {
                if (!this.ItemArray.ContainsKey(this.Columns[index].Name))
                {
                    InitModelCell(index);
                }
                return this.ItemArray[this.Columns[index].Name];
            }

        }                   

        private void InitModelCell(int index)
        {
            DataModelCell cell = new DataModelCell();
            cell.Column = this.Columns[index];
            cell.Model = this;
            cell.Value = null;
            cell.ColumnIndex = index;

            if (!this.ItemArray.ContainsKey(this.Columns[index].Name))
            {
                this.ItemArray.Add(this.Columns[index].Name, cell);
            }
        }

        private void InitModelCell(string columnName)
        {
            DataModelCell cell = new DataModelCell();
            cell.Column = this.Columns[columnName];
            cell.Model = this;
            cell.Value = null;
            cell.ColumnIndex = this.Columns.ToList().IndexOf(cell.Column);
            if (!this.ItemArray.ContainsKey(this.Columns[columnName].Name))
            {
                this.ItemArray.Add(this.Columns[columnName].Name, cell);
            }
        }
        ///// <summary>
        /// 属性访问器,根据列名访问列
        /// </summary>
        /// <param name="name"></param>
        public DataModelCell this[string name]
        {
            get
            {
                if (!this.ItemArray.ContainsKey(name))
                {
                    InitModelCell(name);
                }
                return this.ItemArray[name];
            }

        }
        /// <summary>
        /// 单条查询
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public DataModel Single(string condition)
        {
            return context.Single(this, condition);
        }
        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public int Delete(string condition)
        {
            return context.Delete(this, condition);
        }
        /// <summary>
        /// 保存方法
        /// </summary>
        /// <param name="state"></param>
        /// <returns></returns>
        public string Save(string state)
        {
            return context.Save(this, state);
        }
        /// <summary>
        /// DataRow集合
        /// </summary>
        public DataModelCollection Rows
        {
            get
            {
                if (datamodelCollection == null)
                {
                    datamodelCollection = new DataModelCollection(this);
                }
                return datamodelCollection;
            }
        }
        /// <summary>
        /// 当前数据模型的总数量，即符合condtion查询条件的条目总数
        /// </summary>
        public int TotalCount
        {
            get;
            set;
        }
        /// <summary>
        /// 新增一行
        /// </summary>
        /// <returns></returns>
        public DataModel NewRow()
        {
            return new DataModel(this.context, this.Name);
        }
        /// <summary>
        /// Columns集合
        /// </summary>
        public DataModelColumnCollection Columns
        {
            get
            {
                if (datamodelColumnCollection == null)
                {
                    datamodelColumnCollection = new DataModelColumnCollection(this);
                }
                return datamodelColumnCollection;
            }

        }

        public DataModel Join(DataModel model2, string condtion)
        {
            throw new Exception();
        }
        public Collection<IDataModelEventProcessor> Processors
        {
            get;
            set;
        }
        ///// <summary>
        ///// 根据规则生成主键值
        ///// </summary>
        ///// <returns></returns>
        //public string GeneratePrimaryKey()
        //{
        //    return SequenceNoGeneratorFactory.Generate(this.PrimaryKeyGenType, this.Name, Context).ToString();
        //}
        /// <summary>
        /// 行号
        /// </summary>
        public int RowIndex
        {
            get
            {
                if (this.Parent != null)
                {
                    return this.Parent.Rows.IndexOf(this);
                }
                else
                {
                    return -1;
                }
            }
        }
        /// <summary>
        /// 事件列表
        /// </summary>
        public Collection<DataModelEventInfo> DataModelEvents
        {
            get;
            set;
        }
        /// <summary>
        /// 产生KeyValue
        /// </summary>
        /// <returns></returns>
        public string RenderKeyValue()
        {
            return this.context.RenderKeyValue(this);
        }


    }
}
